package Game;

import java.io.*;
import java.net.*;
import java.util.*;

public class Client extends Socket {
    private BufferedReader in_String;
    private PrintWriter out_String;
    private int myIndex;
    private Server server;
    private int myPort;
    private Vector clients_vector = new Vector();
    private Client[] clients;
    private boolean mainClient;

    public Client(String IP, int port) throws Exception {
        super(IP, port);
        this.mainClient = true;
        initIO();
    }

    public Client(String IP, int port, int index) throws Exception {
        super(IP, port);
        this.myIndex = index;
        this.mainClient = false;
        initIO();
    }

    public Client(Socket socket, int index) throws Exception {
        this.myIndex = index;
        this.mainClient = false;
        initIO(socket);
    }
    
    public void initIO() throws IOException {
        in_String = new BufferedReader(new InputStreamReader(this.getInputStream()));
        out_String = new PrintWriter(this.getOutputStream());
        if (mainClient){
            connectToMain();
        }
    }

    public void initIO(Socket socket) throws IOException{
        in_String = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out_String = new PrintWriter(socket.getOutputStream());
    }

    public int getIndex() {
        return myIndex;
    }

    public void setIndex(int index) {
        this.myIndex = index;
        myPort = (this.myIndex+1)*1111;
        System.out.println("Index: " + myIndex + "\nPort: " + myPort);
    }
    
    private void connectToMain() throws UnknownHostException, IOException {
        setIndex(receiveIntWait());
        sendLine(InetAddress.getLocalHost().toString().split("/")[1]);
        waitForPeerToPeer();
    }

    private void waitForPeerToPeer() {
        requestResponse();
        int user_count = receiveIntWait();                                      //number of players (all registred Clients on MainHost)
        System.out.println("Players: " + user_count);
        try {
            server = new Server(myPort, user_count-myIndex, myIndex);
            sendResponse();
        }
        catch (IOException ex){
            ex.printStackTrace();
        }
        String[] IPs = new String[myIndex+1];
        for (int i = 0; i < myIndex+1; i++){
            IPs[i] = receiveLineWait();
            try {
                clients_vector.addElement(new Client(IPs[i], (i+1)*1111, i));
            }
            catch (Exception ex){
                ex.printStackTrace();
            }
        }
        requestResponse();
        clients = collectClients();
        System.out.println("Client " + (myIndex+1) + ": Ready to Game\nNumber of Clients: " + clients.length);

        try {
            this.close();
        }
        catch (IOException ex){
            ex.printStackTrace();
        }

        new Game(myIndex, clients);
    }
    
    private Client[] collectClients() {
        askForPermission();
        Client[] cfs = server.getClients();                                     //Clients From Server (cfs)
        for (int i = 0; i < cfs.length; i++){
            clients_vector.addElement(cfs[i]);
        }
        Client[] cca = new Client[clients_vector.size()];                       //ClientCollectorArray (cca)
        for (int i = 0; i < cca.length; i++){
            cca[i] = (Client) clients_vector.elementAt(i);
        }
        return cca;
    }

    private void askForPermission() {
        while (!server.isReady()){}
    }

    // <editor-fold defaultstate="collapsed" desc="Send/Receive">
    public void sendInt(int value) {
        sendLine(String.valueOf(value));
    }

    public void sendLine(String line) {
        out_String.println(line);
        out_String.flush();
    }

    public void sendResponse() {
        out_String.println("Response");
        out_String.flush();
    }

    public void sendPacket(Packet packet) {
        out_String.println(packet.toString());
        out_String.flush();
    }

    public int receiveIntWait() {
        return Integer.parseInt(receiveLineWait());
    }

    public String receiveLineWait() {
        String line = null;
        do {
            try {
                line = in_String.readLine();
            }
            catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        while (line.equals(null));
        return line;
    }

    public void requestResponse(){
        String line = null;
        do {
            try {
                line = in_String.readLine();
            }
            catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        while (!line.equals("Response"));
    }

    public Packet receivePacketWait() {
        Packet packet = new Packet(receiveLineWait());
        return packet;
    }// </editor-fold>

}
